// tests showing how to use AAT Tree library to generate assembly code


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
variable declaration and assignment


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;

begin
	x:=999;
	write(x);
end.


--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
variables (blockName, offset) :
	x : ("main", 0)
*/

AATstatement assignmentTest();

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
plus operator for constants test


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;

begin
	x:=999+666;
	write(x);
end.


--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
variables (blockName, offset) :
	x : ("main", 0)
*/

AATstatement plusConstantTest();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
plus operator for variables test


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;
	y:integer;

begin
	x:=999;
	y:=666;
	x:=x+y;
	write(x);
end.


--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 8)
variables (blockName, offset) :
	x : ("main", 0)
	y : ("main", 4)
*/

AATstatement plusVariableTest();
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
"if then else" statement without else part test


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;

begin
	x:=0;
	if 0=0 then x:=999;
	write(x);
	
end.


--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
variables (blockName, offset) :
	x : ("main", 0)
*/

AATstatement ifThenTest();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
"if then else" statement with else part test


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;
	y:integer;

begin
	x:=999;
	if x>1000 then y:=666 else y=111;
	write(y);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 8)
variables (blockName, offset) :
	x : ("main", 0)
	y : ("main", 4)
*/

AATstatement ifThenElseTest();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
"while do" test


-------------------- test in pascal language --------------------------------
Program test;
var
	x:integer;

begin
	x:=0;
	while x<10 do
	begin
		write(x);
		x:=x+1;
	end;
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
variables (blockName, offset) :
	x : ("main", 0)
*/

AATstatement whileDoTest();

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
shows how to build Abstract Assembly Tree for complete pascal program


-------------------- test in pascal language --------------------------------
Program primes;
const MAX=100;
var x,i,occurs:integer;


begin
	i:=2;
	while i<MAX do
	begin
		if i = 2 then
		begin
			write(i);
		end
		else
		begin
			x:=2;
			occurs:= 0;
			while x <= i div 2 do
			begin
				if i mod x = 0 then
				begin
					occurs:=occurs+1;
				end;
				x:=x+1;
			end;
			if occurs = 0 then
			begin
				write(i);
			end;
		end;
		i:=i+1;
	end;
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 12)
variables (blockName, offset) :
	x : ("main", 0)
	i : ("main", 4)
	occurs: ("main", 8)

all constants values must be rewrite to places where they are used -> also semantic amalysis do that	
*/

AATstatement findPrimes();

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
array test


-------------------- test in pascal language --------------------------------
Program ArrayTest;
type
	arrayType = array [10..20] of integer; // baseOffset == 0, elementSize == 4 -> in pascal array left and right limitation are also used! (from 10 to 20 inclusive)
var 
	Avar : arrayType;
	i : integer;

begin
	i:=0;
	while i<=10 do
	begin
		Avar[i+10]:=i*i;
		i:=i+1;
	end;
	write(Avar[11]);
	write(Avar[16]);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", (20-10+1)*4 + 4)
variables (blockName, offset) :
	Avar : ("main", 0)
	i : ("main", (20-10+1)*4 )		// 0 + 4 * (arrayRightIndex - arrayLeftIndex+1); 

*/

AATstatement arrayTest();

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

/*
-------------------- test description ---------------------------------------
record test


-------------------- test in pascal language --------------------------------
Program test;

type
	posType = record
		x,y : integer;
	end;
var
	i:integer;
	p:posType;

begin
	p.x:=666;
	p.y:=999;
	write(p.x);
	write(p.y);
end.


--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4+8)
variables (blockName, offset) :
	i : ("main", 0)
	p : ("main", 4 )

*/

AATstatement recordTest();

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//												PROCEDURE TESTS
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

/*
IMPORTANT NOTICE:

1. In Allocation statement MemoryAlocation for main block body is obligatory, and the block name must be "main". "main" identifier is reserved for program main body. 
2. AATexpressionList in Allocation statement must finish with NULL statement
2. Use MemoryAllocation for every procedure, even it (procedure or block) does not have any declared data (Memoryallocation with 0 bytes).
3. for procedures with arguments list, arguments are in reverse order, ex. having procedure:
	procedure proc(x1,x2,x3 : integer);
	offset calculation begins in x3, so:
	offset(x3)==0, offset(x2)==4, offset(x1)==8. For every next variable declaration in procedure body offsets calculation starts in next free value -
	in example proc it will be 12
4. In ProcedureDefinition statement use procedure identifier (same as in MemoryAllocation) first (it marks begining of the procedure block), and after that use this identifier with "_end" sufix, or whatever you want (it marks the end of the procedure block)
5. Second argument in ProcedureDefinition is size of arguments (which are passed as value [copy] ) in bytes
6. Passing arguments to procedure through reference don't alocate memory for them. Use memory addressing convention (blockName, variable offset) using reference arguments. Semantic analiser should cope with it. Having procedure like this:
	procedure P(x:integer; var y:integer; z : integer);
	begin
	end;
you will allocate 8 bytes for procedure P and offsets -> offset(x)==4, offset(z)==0

	


*/

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
the simplest procedure invocation. Procedure with empty arguments list. Just to show how invocation works.


-------------------- test in pascal language --------------------------------
Program test;

procedure proc1();
begin
	write(666);
end;

begin
	proc1();
	write(999);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 0)
	("proc1", 0)

*/

AATstatement simpleProcedureInvocation();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
nested procedure invocation. Procedures with empty arguments list.


-------------------- test in pascal language --------------------------------
Program test;

procedure proc2();
begin
	write(333);
end;

procedure proc1();
begin
	proc2();
	write(666);
end;

begin
	proc1();
	write(999);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 0)
	("proc1", 0)
	("proc2", 0)
*/

AATstatement nestedProcedureInvocation();



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
procedure with arguments list. Arguments are passed through value (copy)


-------------------- test in pascal language --------------------------------
Program test;

var z:integer;

// offsets in procedure argument list are given in reverse order!
//	offset(x)==4
//	offset(y)==0
//	offset(diff)==8

procedure subProcedure(x:integer; y:integer);
	var diff:integer;
	begin
		diff:=x-y;
		write(diff);
	end;

// offsets starts from 0 in each blockBody -> for procedures and functions offset counting starts even in the argument lists

//offset(z)==0
begin
	z:=666;
	subProcedure(z,66);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
	("subProcedure", 12)
variables (blockName, offset) :
	z : ("main", 0)
	x : ("subProcedure", 4 )
	y : ("subProcedure", 0 )
	diff: ("subProcedure", 8)
*/


AATstatement procedureWithArgumentsTest();



//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
procedure with arguments list. Arguments are passed through reference


-------------------- test in pascal language --------------------------------
Program test;

var
	r:integer

procedure refProc(var ref : integer);
	begin
		ref:=2000;
	end;

begin
	r:=1000;
	write(r);
	subProcedure(r);
	write(r);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 4)
	("subProcedure", 0)	// passing arguments through reference don't alocate memory for them. Use memory addressing convention (blockName, variable offset) for 						//reference arguments. Semantic analiser should cope with it.
variables (blockName, offset) :
	r : ("main", 0)
*/

AATstatement procedureVarReferenceTest();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
procedure with tail recursion


-------------------- test in pascal language --------------------------------
Program test;

procedure recursion(x:integer);
begin
	if x<5 then recursion(x+1);
	write(x);
end;

begin
	recursion(0);
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 0)
	("recursion", 4)
variables (blockName, offset) :
	x : ("recursion", 0)
*/

AATstatement tailRecursionTest();


//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
-------------------- test description ---------------------------------------
a big test: quick sort program


-------------------- test in pascal language --------------------------------
Program test;

type
	arrType = array[1..20] of integer;

var
	arr : arrType;

procedure fillArray();
var
	i : integer;
begin
	i:=1;
	while i<=20 do
	begin
		arr[i]:= ( 20 - i ) mod 6;
		i:=i+1;
	end;
end;

procedure printArray();
var
	i : integer;
begin
	i:=1;
	while i<=20 do
	begin
		write(arr[i], ' ');
		i:=i+1;
	end;
end;

procedure quickSort(var A : arrType; lo, hi : integer);
var
	i,j,h,x,t : integer;
begin
//  lo is the lower index, hi is the upper index of the region of array a that is to be sorted
	i:=lo;
	j:=hi;
    // comparison element x
	x:=A[(lo+hi)div 2];
	t:=1;
	while t=1 do
	begin
		while A[i]<x do i:=i+1;
		while A[j]>x do j:=j-1;
		if i<=j then
		begin
			h:=a[i]; a[i]:=a[j]; a[j]:=h;
			i:=i+1;
			j:=j-1;
		end;
		if i>j then t:=0;
	end;

	if lo<j then quickSort(A, lo, j);
	if i<hi then quickSort(A,i, hi);
	
end;

begin
	fillArray();
	printArray();
	writeln();
	quickSort(arr, 1, 20);
	printArray();
end.

--------- data collected by Semantic Analyser used to build AAT -------------
blocks (blockName, data size in bytes) :
	("main", 40)		//for an array
	("fillArray", 4)
	("printArray", 4)
	("quickSort", 28)
variables (blockName, offset) :
	arr : ("main", 0)
	i : ("fillArray", 0)
	i : ("printArray", 0)
	hi : ("quickSort", 0)
	lo : ("quickSort", 4)
	i : ("quickSort", 8)
	j : ("quickSort", 12)
	h : ("quickSort", 16)
	x : ("quickSort", 20)
	t : ("quickSort", 24)
*/

AATstatement quickSort();


